package droid.frame.utils.http;

import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
import java.util.UUID;

import droid.frame.utils.android.Log;
import droid.frame.utils.rsa.RSAUtils;

/**
 * 通用的http工具类<br>
 * 每次网络请求由一个单独的HttpClient对象处理<br>
 * 每个HttpClient不管是get还是post都关联一个HttpReq或者HttpPost对象
 *
 * @author coffee
 */
public class HttpClient {
    public static boolean isRAS = false;//是否进行加密  火箭投递加密  火箭联盟不加密
    private final String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCQgiFlfD7MRpd1u3Dz6PDR13njfqbT+zys9PFCbjCzSePFvBszZVZtw+MFuEIWK3/vFAZ/ur9zAAkq19k4QRHmqhbsbY47IatutYiOkwpHBp4uSkqYkNUH4oAs49qM1Pp8dzAZiY1einqeDI3Gs7EnZjWYHppVYuV6rJrlkdc6YwIDAQAB";
    private Object currHttp;

    private String charset = "UTF-8";

    // 检查网络类型
    public synchronized static boolean checkNetworkStatus(final Activity context) {
        ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        connManager.getActiveNetworkInfo();
        // 网络状态
        boolean netSataus = false;
        NetworkInfo info = connManager.getActiveNetworkInfo();
        if (info != null) {
            netSataus = info.isAvailable();
        }
        return netSataus;
    }

    // 关闭http请求
    public void abort() {
        if (this.currHttp != null) {
            if (this.currHttp instanceof HttpURLConnection) {
                HttpURLConnection conn = (HttpURLConnection) this.currHttp;
                conn.disconnect();
            }
        }
    }

    /**
     * post方式提交数据
     *
     * @param baseUrl   ： url
     * @param paramsMap : 参数集
     * @param paramsMap : 编码方式
     */
    public Object post(String baseUrl, Map<String, Object> paramsMap) {
        try {
            URL url = new URL(baseUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            currHttp = conn;
            conn.setConnectTimeout(1000 * 10);// 设置连接超时时间
            // 允许Input、Output，不使用Cache
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            byte[] bytes = null;
            if (isRAS) {
                conn.setRequestProperty("User-Agent", System.getProperty("http.agent") + "**rsa**");
                bytes = RSAUtils.encryptByPublicKey(getParamsString(paramsMap).getBytes(charset), publicKey);
            } else {
                bytes = getParamsString(paramsMap).getBytes(charset);
            }
            // 写入body
            DataOutputStream out = new DataOutputStream(conn.getOutputStream());
            out.write(bytes);
            out.close();
            // 读取返回的数据
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset));
            String line = null;
            StringBuilder sb = new StringBuilder();
            while ((line = in.readLine()) != null) {
                sb.append(line);
            }
            in.close();
            return sb.toString();
        } catch (java.net.SocketTimeoutException e) {
            return MsgID.http_time_out;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    // public String postWithImage(String url, Map<String, Object> paramsMap) {
    // String doc = "";
    // DefaultHttpClient httpClient = new DefaultHttpClient();
    // HttpContext localContext = new BasicHttpContext();
    // HttpPost httpPost = new HttpPost(url);
    // try {
    // MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    // /* example for setting a HttpMultipartMode */
    // builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
    // for (String paramName : paramsMap.keySet()) {
    // String paramValue = paramsMap.get(paramName);
    // if (paramValue == null) {
    // continue;
    // }
    // // 文件
    // if (paramValue.startsWith("/")) {
    // builder.addPart(paramName, new FileBody(new File(paramValue)));
    // } else {
    // String encodeValue = URLEncoder.encode(paramValue, "UTF-8");
    // builder.addPart(paramName, new StringBody(encodeValue, ContentType.TEXT_PLAIN));
    // }
    // }
    // //
    // httpPost.setEntity(builder.build());
    // HttpResponse response = httpClient.execute(httpPost, localContext);
    // HttpEntity resEntity = response.getEntity();
    // if (resEntity != null) {
    // doc = EntityUtils.toString(resEntity);
    // Log.i(TAG, doc);
    // }
    // } catch (IOException e) {
    // e.printStackTrace();
    // }
    // return doc;
    // }

    /**
     * 上传文件
     *
     * @param requestUrl
     * @param file
     * @return
     */
    public static String postFile(String requestUrl, File file) {
        Log.i("app:http", requestUrl + " " + file.getAbsolutePath());
        String end = "\r\n";
        String twoHyphens = "--";
        String boundary = "*****";
        String newName = file.getName();
        StringBuffer sb = new StringBuffer();
        try {
            URL url = new URL(requestUrl);
            HttpURLConnection con = (HttpURLConnection) url.openConnection();
            // 允许Input、Output，不使用Cache
            con.setDoInput(true);
            con.setDoOutput(true);
            con.setUseCaches(false);
            // 设置以POST方式进行传送
            con.setRequestMethod("POST");
            // 设置RequestProperty
            con.setRequestProperty("Connection", "Keep-Alive");
            con.setRequestProperty("Charset", "UTF-8");
            con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
            // 构造DataOutputStream流
            DataOutputStream out = new DataOutputStream(con.getOutputStream());
            out.writeBytes(twoHyphens + boundary + end);
            out.writeBytes("Content-Disposition: form-data; " + "name=\"userFile\";fileName=\"" + newName + "\"" + end);
            out.writeBytes(end);
            // 构造要上传文件的FileInputStream流
            FileInputStream fin = new FileInputStream(file);
            // 设置每次写入1024bytes
            int bufferSize = 1024;
            byte[] buffer = new byte[bufferSize];
            int length = -1;
            // 从文件读取数据至缓冲区
            while ((length = fin.read(buffer)) != -1) {
                // 将资料写入DataOutputStream中
                out.write(buffer, 0, length);
            }
            out.writeBytes(end);
            out.writeBytes(twoHyphens + boundary + twoHyphens + end);
            out.flush();
            // 关闭流
            fin.close();
            // 关闭DataOutputStream
            out.close();
            // 获取响应流
            InputStream ins = con.getInputStream();
            int ch;
            while ((ch = ins.read()) != -1) {
                sb.append((char) ch);
            }
            ins.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.i("app:http", sb.toString());
        return sb.toString();
    }

    /**
     * @param linkUrl
     * @param returnType : type==0返回字符串 type==1 返回byte[]数组
     * @return 返回408 请求超时
     * @throws IOException java.net.UnknownHostException: Host is unresolved: not-a-legal-address:80
     */
    public Object get(String linkUrl, Integer... returnType) {
        try {
            if (linkUrl == null || linkUrl.trim().equals("")) {
                return "";
            }
            URL url = new URL(linkUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            currHttp = conn;
            // 允许Input、Output，不使用Cache
            conn.setDoInput(true);
            conn.setDoOutput(false);
            conn.setUseCaches(false);
            conn.setRequestMethod("GET");
            // 读取返回的数据
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), charset));
            String line = null;
            StringBuilder sb = new StringBuilder();
            while ((line = in.readLine()) != null) {
                sb.append(line);
            }
            in.close();
            return sb.toString();
        } catch (SocketTimeoutException e) {
            e.printStackTrace();
            return 408;
        } catch (Exception e) {
            e.printStackTrace();
            // conn.setDoOutput(true); 会导致 java.io.FileNotFoundException: http://guoer.shouhuobao.com:9980/guoer-appserv/evaluate/459/109071?toastNet=true&device=1&post=false&version=3023&
            // 如果wifi有问题 . 即是连上了wifi但是不能访问internet会抛如下异常
            // org.apache.http.conn.HttpHostConnectException: Connection to
            // http://192.168.226.30 refused
        }
        return "";
    }

    /**
     * android上传文件到服务器
     * <p>
     * 下面为 http post 报文格式
     * <p>
     * POST/logsys/home/uploadIspeedLog!doDefault.html HTTP/1.1 Accept: text/plain, Accept-Language: zh-cn Host: 192.168.24.56
     * Content-Type:multipart/form-data;boundary=-----------------------------7db372eb000e2 User-Agent: WinHttpClient Content-Length: 3693 Connection: Keep-Alive 注：上面为报文头
     * -------------------------------7db372eb000e2 Content-Disposition: form-data; name="file"; filename="kn.jpg" Content-Type: image/jpeg (此处省略jpeg文件二进制数据...）
     * -------------------------------7db372eb000e2--
     *
     * @param picPaths   需要上传的文件路径集合
     * @param requestURL 请求的url
     * @return 返回响应的内容
     */
    public static String postFiles(String requestURL, String... picPaths) {
        String boundary = UUID.randomUUID().toString(); // 边界标识 随机生成
        String prefix = "--", end = "\r\n";
        String content_type = "multipart/form-data"; // 内容类型
        String CHARSET = "utf-8"; // 设置编码
        int TIME_OUT = 60 * 1000; // 超时时间
        try {
            URL url = new URL(requestURL);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(TIME_OUT);
            conn.setConnectTimeout(TIME_OUT);
            conn.setDoInput(true); // 允许输入流
            conn.setDoOutput(true); // 允许输出流
            conn.setUseCaches(false); // 不允许使用缓存
            conn.setRequestMethod("POST"); // 请求方式
            conn.setRequestProperty("Charset", "utf-8"); // 设置编码
            conn.setRequestProperty("connection", "keep-alive");
            conn.setRequestProperty("Content-Type", content_type + ";boundary=" + boundary);
            /**
             * 当文件不为空，把文件包装并且上传
             */
            OutputStream outputSteam = conn.getOutputStream();
            DataOutputStream dos = new DataOutputStream(outputSteam);

            String name = "userFile";

            for (int i = 0; i < picPaths.length; i++) {
                if (picPaths[i] == null) {
                    continue;
                }
                File file = new File(picPaths[i]);
                if (file.exists() == false) {
                    continue;
                }
                StringBuffer sb = new StringBuffer();
                sb.append(prefix);
                sb.append(boundary);
                sb.append(end);

                /**
                 * 这里重点注意： name里面的值为服务器端需要key 只有这个key 才可以得到对应的文件 filename是文件的名字，包含后缀名的 比如:abc.png
                 */
                sb.append("Content-Disposition: form-data; name=\"" + name + "\"; filename=\"" + file.getName() + "\"" + end);
                sb.append("Content-Type: application/octet-stream; charset=" + CHARSET + end);
                sb.append(end);
                dos.write(sb.toString().getBytes());

                InputStream is = new FileInputStream(file);
                byte[] bytes = new byte[8192];// 8k
                int len = 0;
                while ((len = is.read(bytes)) != -1) {
                    dos.write(bytes, 0, len);
                }
                is.close();
                dos.write(end.getBytes());// 一个文件结束标志
            }
            byte[] end_data = (prefix + boundary + prefix + end).getBytes();// 结束 http 流
            dos.write(end_data);
            dos.flush();
            /**
             * 获取响应码 200=成功 当响应成功，获取响应的流
             */
            int res = conn.getResponseCode();
            if (res == 200) {
                // 获取响应流
                StringBuffer stringBuffer1 = new StringBuffer();
                InputStream ins = conn.getInputStream();
                int ch;
                while ((ch = ins.read()) != -1) {
                    stringBuffer1.append((char) ch);
                }
                ins.close();
                return stringBuffer1.toString();
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public static String getParamsString(Map<String, Object> params) {
        if (params == null) {
            return "";
        } else {
            StringBuilder sb = new StringBuilder();
            for (String key : params.keySet()) {
                Object value = params.get(key);
                if (value == null) {
                    continue;
                }
                sb.append(key);
                sb.append("=");
                sb.append(value);
                sb.append("&");
            }
            String result = sb.toString();
            return result;
        }
    }

    /**
     * 获取编码后的变量值
     *
     * @return
     */
    public static String getEncodeParam(String param) {
        if (param == null) {
            return null;
        }
        try {
            String encodeStr = URLEncoder.encode(param, "UTF-8");
            return encodeStr;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return param;
    }

}
